package admin

import (
	"context"
	"encoding/json"

	"suci-go-zero/common/xerr"
	"suci-go-zero/internal/model"
	"suci-go-zero/internal/svc"
	"suci-go-zero/internal/types"

	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
)

type MenuListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewMenuListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MenuListLogic {
	return &MenuListLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *MenuListLogic) MenuList() (resp *types.MenuList, err error) {
	resp = &types.MenuList{
		Menu: []*types.MenuItem{},
	}
	menus := []*types.MenuItem{}

	rb := l.svcCtx.Models.Menu.RowBuilder()
	menuList, err := l.svcCtx.Models.Menu.FindAll(l.ctx, rb, "sort desc")
	if err != nil && err != model.ErrNotFound {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查找菜单 数据库错误%v", err)
	}

	if err == model.ErrNotFound {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_NOT_FOUND_ERR), "查找菜单列表为空%v", err)
	}

	for _, item := range menuList {
		// logx.Infof("menu_item %+v", item)
		menu := types.MenuItem{
			Id:        item.Id,
			Pid:       item.ParentId,
			Name:      item.Name,
			Path:      item.Path,
			Meta:      types.Meta{},
			Component: item.Component,
			Redirect:  item.Redirect,
			Sort:      item.Sort,
			Children:  []*types.MenuItem{},
			ApiList:   []*types.ApiList{},
		}
		meta := &types.Meta{}
		err = json.Unmarshal([]byte(item.Meta), meta)
		if err != nil {
			logx.Info(err)
		}
		menu.Meta = *meta
		menus = append(menus, &menu)
	}

	rb = l.svcCtx.Models.MenuApi.RowBuilder()
	apiList, err := l.svcCtx.Models.MenuApi.FindAll(l.ctx, rb, "")
	if err != nil && err != model.ErrNotFound {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查找apiList 数据库错误%v", err)
	}
	MenuApiTree := make(map[int64][]*types.ApiList)
	for _, api := range apiList {
		apiItem := types.ApiList{
			Id:     api.Id,
			Code:   api.Code,
			Url:    api.Url,
			MenuId: api.MenuId,
		}
		if MenuApiTree[api.MenuId] != nil {
			MenuApiTree[api.MenuId] = append(MenuApiTree[api.MenuId], &apiItem)
		} else {
			MenuApiTree[api.MenuId] = []*types.ApiList{&apiItem}
		}
	}
	for _, menu := range menus {
		if MenuApiTree[menu.Id] != nil {
			menu.ApiList = MenuApiTree[menu.Id]
		}
	}

	resp.Menu = getTreeRecursive(menus, 0)

	return resp, nil
}
